var express = require('express');
var session = require('express-session');
var http = require('http');

var Provider = require('./lib/msvc-util').Provider;
var _ = require('lodash');
var fs = require('fs');

var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();
var app = express();

var subProvider = new Provider({
  url: 'http://localhost:8080',
  // url: 'http://localhost:8080',
  contextPath: '/hrsystem'
});

app.use(session({
  secret: 'keyboard cat'
}));

function haveRightToAccess(currentRole, roles) {
  if (!roles) {
    return false;
  }

  console.log(typeof roles);
  if (typeof roles == "string") {
    return currentRole === roles;
  }

  if (typeof roles == "object") {
    for (var i in roles) {
      console.log(roles[i]);
      if (roles[i] === currentRole) {
        return true;
      }
    }
  }
  return false;
}

function requireRole(roles) {
  return function(req, res, next) {
    var user = req.session.user;
    console.log('require roles: ' + roles);
    console.log('user info: ' + user.role);
    if (user && haveRightToAccess(user.role, roles)) {
      next();
    } else {
      res.send(403);
    }
  }
}

function storeUserInSession(req, res) {
  var url = subProvider.getUrlPath(req.url.replace('/api', ''));
  console.log('Forwarding ' + req.method + ' request to %s', url);

  req.pipe(subProvider.request({
      url: url,
      body: req.body,
      json: true
    }))
    .on('response', function(response) {
      console.log('Response for ' + response.request.method + ' on "' + this.path + '", Status Code: ' + response.statusCode);
    })
    .on('data', function(d) {
      try {
        var user = JSON.parse(d);
        req.session.user = user;
        console.log('login user:', d);
      } catch (err) {
        console.log(err);
      }
    })
    .on('error', function(err) {
      console.log('hrsystem-api: error while forwarding API call', err.stack);
      res.status(500).end();
    })
    .pipe(res);
}


function handleRequest(req, res) {
  var url = subProvider.getUrlPath(req.url.replace('/api', ''));
  console.log('Forwarding ' + req.method + ' request to %s', url);
  req.pipe(subProvider.request({
      url: url,
      body: req.body,
      json: true
    }))
    .on('response', function(response) {
      console.log('Response for ' + response.request.method + ' on "' + this.path + '", Status Code: ' + response.statusCode);
    })
    .on('error', function(err) {
      console.log('hrsystem-api: error while forwarding API call', err.stack);
      res.status(500).end();
    })
    .pipe(res);
}

app.get('/api/isloggedin', function(req, res) {
    var user = req.session.user;
    if (user == null || user == 'undefined') {
      console.log('user', JSON.stringify(user));
      res.sendfile('./app/views/login.html');
    } else if (user.role == null || user.role == 'undefined') {
      console.log('user', JSON.stringify(user.role));
      res.sendfile('./app/views/login.html');
    } else {
      res.send('OK');
    }
  })
  // attachment api
app.post('/attachment*', multipartMiddleware, function(req, res) {
  var idparam = "";
  var url = subProvider.getUrlPath(req.url);
  var reg = new RegExp("(^|&)" + "id" + "=([^&]*)(&|$)", "i");
  var index = url.indexOf("?");
  var r = url.substr(index + 1).match(reg);
  if (r != null) idparam = unescape(r[2]);
  console.log('param:', idparam);
  if (req.files && req.files.file != 'undifined') {
    var boundaryKey = Math.random().toString(16);
    var options = {
      host: 'localhost',
      port: 8088,
      path: '/attachment',
      method: 'POST'
    };

    var reqHttps = http.request(options, function(resHttps) {
      resHttps.on('data', function(body1) {
        console.log("hello:" + body1);
        var responseImage = JSON.parse(body1);
        var imagePath = responseImage.value.path.replace('\\', '/');
        var str = "<script>window.opener.document.getElementById('" + idparam + "').value = '" + imagePath + "';" +
          "window.opener.document.getElementById('" + idparam + "Img').src ='/api/" + imagePath + "';" +
          "window.opener.document.getElementById('" + idparam + "Img').style.display = 'block';</script>";
        var ret = "<html><head></head><body><a>上传成功</a><image src='/api/" + responseImage.value.path + "'/>" + str + "</body></html>";
        res.send(ret);
      });
    });

    var payload = '--' + boundaryKey + '\r\n' + 'Content-Type: ' + req.files.file.headers["content-type"] + '\r\n' + 'Content-Disposition: form-data; name="file"; filename="' + req.files.file.name + '"\r\n' + 'Content-Transfer-Encoding: binary\r\n\r\n';

    var enddata = '\r\n--' + boundaryKey + '--';
    reqHttps.setHeader('Content-Type', 'multipart/form-data; boundary=' + boundaryKey + '');
    reqHttps.setHeader('Content-Length', Buffer.byteLength(payload) + Buffer.byteLength(enddata) + req.files.file.size);

    reqHttps.write(payload);
    var fileStream = fs.createReadStream(req.files.file.path, {
      bufferSize: 4 * 1024
    });
    fileStream.pipe(reqHttps, {
      end: false
    });

    fileStream.on('end', function() {
      reqHttps.end(enddata);
    });

    reqHttps.on('error', function(e) {
      console.error("error:" + e);
      var ret = {
        "code": -1
      };
      res.send(ret);
    });
  }
});
//report export api
app.get('/api/attachment/:id', handleRequest);
app.get('/api/dir/export', handleRequest);
app.get('/api/hr/sum/export/:year/:month/:region/:cluster', handleRequest);
app.get('/api/gcpp/sum/export/:year', handleRequest);
app.get('/api/sub/export/:year/:month', handleRequest);
app.get('/api/leader/export/:year/:month', handleRequest);
app.get('/api/staffingb/export/:year/:month', handleRequest);
app.get('/api/tr/sum/export/:year/:region', handleRequest);
app.get('/api/tr/sum/export/hotel/:year/:region', handleRequest);
app.get('/api/training/export/monthly/:year/:hotelId', handleRequest);
app.get('/api/hr/export/monthly/:year/:hotelId', handleRequest);
app.get('/api/preopen/export/task/:hotelId', handleRequest);
app.get('/api/preopen/export/people/:hotelId', handleRequest);
app.get('/api/preopen/target/export/:hotelId', handleRequest);
app.get('/api/preopen/export/completion', handleRequest);
app.get('/api/preopen/export/ytd', handleRequest);
app.get('/api/preopen/export/recruit', handleRequest);


//app.get('/api/upload/:id', handleRequest);
// HR turnover api
app.post('/api/hr/turnover/depart',requireRole(["Operating"]), handleRequest);
app.get('/api/hr/turnover/depart/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.get('/api/hr/turnover/leader/summary/:year/:month',requireRole(["Operating","ADMIN"]),  handleRequest);
app.get('/api/hr/turnover/leader/:year/:month/:hotelId',requireRole(["Operating", "ADMIN"]),  handleRequest);
app.post('/api/hr/turnover/leader', requireRole(["Operating"]), handleRequest);
app.post('/api/hr/turnover/depart/report/depart',requireRole(["Operating","ADMIN"]),  handleRequest);
app.post('/api/hr/turnover/depart/report/period',requireRole(["Operating","ADMIN"]),  handleRequest);
app.post('/api/hr/turnover/depart/report/band', requireRole(["Operating","ADMIN"]), handleRequest);

// app.get('/api/hr/turnover/interview/summary/:year/:month', handleRequest);
app.get('/api/hr/turnover/interview/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/turnover/interview',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/turnover/interview/sum/type',requireRole(["Operating","ADMIN"]),  handleRequest);
app.get('/api/hr/turnover/interview/sum/type/:year/:month/:hotel',requireRole(["Operating","ADMIN"]),  handleRequest);
app.post('/api/hr/turnover/interview/sum/top',requireRole(["Operating","ADMIN"]),  handleRequest);
app.get('/api/hr/turnover/interview/sum/top/:year/:month/:hotel',requireRole(["Operating","ADMIN"]),  handleRequest);

//HR Staffing 
app.get('/api/hr/staffing/table1/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/staffing/table1',requireRole(["Operating"]),  handleRequest);
app.get('/api/hr/staffing/table2/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/staffing/table2',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/staffing/table1/report',requireRole(["ADMIN"]),  handleRequest);
// HR directory
app.get('/api/hr/directory/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/directory',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/directory/report',requireRole(["ADMIN"]),  handleRequest);

// HR feedback
app.post('/api/hr/feedback/report',requireRole(["ADMIN"]),  handleRequest);

app.get('/api/hr/feedback/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/feedback',requireRole(["Operating"]),  handleRequest);


//HR recruiment
app.get('/api/hr/recruiment/report/:year/:month',requireRole(["Operating","ADMIN"]),  handleRequest);
app.get('/api/hr/recruiment/report/:year/:month/:hotelId',requireRole(["Operating","ADMIN"]),  handleRequest);
app.get('/api/hr/recruiment/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/recruiment',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/recruiment/report',requireRole(["Operating","ADMIN"]),  handleRequest);


//HR recognition
app.post('/api/hr/recognition/report',requireRole(["ADMIN"]),  handleRequest);

app.get('/api/hr/recognition/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/recognition',requireRole(["Operating"]),  handleRequest);

//HR pathway
app.get('/api/hr/pathway/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/pathway',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/pathway/report',requireRole(["ADMIN"]),  handleRequest);
//HR people planning
app.get('/api/hr/people/:hotelId',requireRole(["Operating"]), handleRequest);
app.post('/api/hr/people',requireRole(["Operating"]),  handleRequest);
app.post('/api/hr/people/report',requireRole(["ADMIN"]),  handleRequest);
app.post('/api/hr/people/single',requireRole(["ADMIN"]),  handleRequest);
app.post('/api/hr/people/vreport',requireRole(["ADMIN"]),  handleRequest);
app.post('/api/hr/people/vreporttop',requireRole(["ADMIN"]),  handleRequest);
app.post('/api/hr/people/getbyregion',requireRole(["Operating","ADMIN"]),  handleRequest);

//Training api
app.get('/api/tr/budget/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/tr/budget',requireRole(["Operating"]),  handleRequest);

app.get('/api/tr/employee/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/tr/employee',requireRole(["Operating"]),  handleRequest);

app.get('/api/tr/manager/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/tr/manager',requireRole(["Operating"]), handleRequest);

app.get('/api/tr/external/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/tr/external',requireRole(["Operating"]),  handleRequest);

app.get('/api/tr/cross/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/tr/cross',requireRole(["Operating"]),  handleRequest);

app.get('/api/tr/other/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/tr/other',requireRole(["Operating"]),  handleRequest);

app.get('/api/tr/depart1/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/tr/depart1',requireRole(["Operating"]),  handleRequest);

app.get('/api/tr/depart2/:year/:month/:hotelId',requireRole(["Operating"]),  handleRequest);
app.post('/api/tr/depart2',requireRole(["Operating"]),  handleRequest);

app.post('/api/tr/sum/report', requireRole(["ADMIN"]), handleRequest);



//Preopen api
app.get('/api/preopen/task/:hotelId',requireRole(["PreOpening"]), handleRequest);
app.post('/api/preopen/task',requireRole(["PreOpening"]),  handleRequest);
app.get('/api/preopen/task/alltasks',requireRole(["PreOpening"]), handleRequest);
app.post('/api/preopen/recruiment',requireRole(["PreOpening"]), handleRequest);
app.get('/api/preopen/recruiment/:hotelId',requireRole(["PreOpening"]), handleRequest);
app.post('/api/preopen/target',requireRole(["PreOpening"]), handleRequest);
app.get('/api/preopen/target/:hotelId',requireRole(["PreOpening"]), handleRequest);
app.get('/api/preopen/sum/comp/:hotelId',requireRole(["PreOpening"]),  handleRequest );
app.get('/api/preopen/sum/completion',requireRole(["ADMIN"]),  handleRequest );
app.get('/api/preopen/sum/ytd',requireRole(["ADMIN"]),  handleRequest );
app.get('/api/preopen/sum/recruit',requireRole(["ADMIN"]),  handleRequest );

//Admin api
app.get('/api/hotels/preopen', requireRole(["ADMIN"]),  handleRequest);
app.post('/api/hotels',requireRole(["ADMIN"]),  handleRequest);
app.get('/api/hotels',requireRole(["ADMIN"]),  handleRequest);
app.get('/api/hotels/region/:id',requireRole(["ADMIN"]),  handleRequest);
app.delete('/api/hotels/:id',requireRole(["ADMIN"]),  handleRequest);
app.get('/api/hotels/:id',requireRole(["ADMIN"]),  handleRequest);


// user api
app.post('/api/user/login', storeUserInSession);
app.get('/api/user/logout', handleRequest);
app.get('/api/common/gethotelname/:code', handleRequest);
app.get('/api/common/getregions', handleRequest);
app.get('/api/common/getclusters/:regionId', handleRequest);
app.post('/api/user/password/:token', handleRequest);
app.post('/api/user/password', handleRequest);
app.get('/api/user/modify/:code', handleRequest);
app.get('/api/progress/:year/:month/:hotelId', handleRequest);
app.get('/api/progress/sum/:year/:month',handleRequest);
app.get('/api/progress/sum/all/:year/:month',handleRequest);
app.get('/api/setting/current',requireRole(["ADMIN","Operating","PreOpening"]),  handleRequest);
app.get('/api/setting/current/:year/:month', requireRole(["ADMIN"]), handleRequest);
app.get('/api/setting',requireRole(["ADMIN","Operating","PreOpening"]),  handleRequest);
app.post('/api/setting',requireRole(["ADMIN"]),  handleRequest);



app.post('/api/user', requireRole(["ADMIN"]), handleRequest);
app.delete('/api/user/:id', requireRole(["ADMIN"]), handleRequest);
app.get('/api/user/:id', requireRole(["ADMIN", "REVENUER"]), handleRequest);
app.all('/api/user', requireRole(["ADMIN"]), handleRequest);


app.get('/', function(req, res) {
  res.sendfile('./app/index.html');
});

app.use(express.static('./app'));

var server = app.listen(80, function() {
  var host = server.address().address;
  var port = server.address().port;

  console.log('Example app listening at http://%s:%s', host, port);
});